/// Author: QP
/// Version: 1.0
/// Date: 2021/08/04
/// HCC SQL schema 工具类
/// 
Class HCC.SQL.Tools Extends %RegisteredObject
{

/// 章节类与文档类为关系属性的列表
Parameter tRSList = "HCC.SQL.Document.HighValueConsumable,HCC.SQL.Document.NursingObservation,HCC.SQL.Document.Symptom,HCC.SQL.Document.MedicationAdministered,HCC.SQL.Document.PhysicalExam,HCC.SQL.Document.FamilyHistory,HCC.SQL.Document.VitalSign,HCC.SQL.Document.Vaccination,HCC.SQL.Document.NursingOperation,HCC.SQL.Document.SupplementaryExam,HCC.SQL.Document.SurgicalOperationNotePostoperativeDX,HCC.SQL.Document.Anesthesia,HCC.SQL.Document.Skin,";

/// 根据文档编号，产生互联互通XML文档。它从文档SQL表中查找对应文档编号的数据，并产生相应的文档
/// pDocNo: 文档号
/// pDoc：产生的XML文档，以字符串保存
/// 返回值为%Status，标识是否产生成功
ClassMethod GenerateHCCDocument(pDocNo = "Doc1", Output pDoc As %Stream.TmpCharacter) As %Status
{
    Set tErrlog="", tSC = $$$OK    
    // 初始化章节列表（section list）
    Set tSec("文档头")=$LB("Header","HCC.SQL.Document.Header")
    Set tSec("既往史章节")=$LB("PastHistory","HCC.SQL.Document.PastHistory")
    Set tSec("月经史章节")=$LB("Menstrual","HCC.SQL.Document.MenstrualHistory")
    Set tSec("过敏史章节")=$LB("Allergy","HCC.SQL.Document.Allergy")
    Set tSec("住院史章节")=$LB("Hospitalization","HCC.SQL.Document.Hospitalization")
    Set tSec("住院过程章节")=$LB("HospitalCourse","HCC.SQL.Document.HospitalCourse")
    Set tSec("诊断记录章节")=$LB("Diagnosis","HCC.SQL.Document.Diagnosis")
    Set tSec("主要健康问题章节")=$LB("Problem","HCC.SQL.Document.HealthProblem")
    Set tSec("转科记录章节")=$LB("Referral","HCC.SQL.Document.Referral")
    Set tSec("出院诊断章节")=$LB("DisDiag","HCC.SQL.Document.HospitalDischargeDX")
    Set tSec("入院诊断章节")=$LB("AdmDiag","HCC.SQL.Document.HospitalAdmissionDX")
    Set tSec("术前诊断章节")=$LB("PreOpDiag","HCC.SQL.Document.SurgicalOperationNotePreoperativeDX")
    Set tSec("术后诊断章节")=$LB("PostOpDiags","HCC.SQL.Document.SurgicalOperationNotePostoperativeDX")
    Set tSec("实验室检查章节")=$LB("LabTest","HCC.SQL.Document.LabTest")
    Set tSec("医嘱章节")=$LB("ProviderOrder","HCC.SQL.Document.ProviderOrder")
    Set tSec("手术操作章节")=$LB("Procedure","HCC.SQL.Document.Procedure")
    Set tSec("手术过程描述章节")=$LB("ProcedureNote","HCC.SQL.Document.ProcedureNote")
    Set tSec("宫剖产手术操作章节")=$LB("CaesareanProcedure","HCC.SQL.Document.CaesareanProcedure")
    Set tSec("引流章节")=$LB("SurgicalDrains","HCC.SQL.Document.SurgicalDrains")
    Set tSec("用药史章节")=$LB("MedicationUseHistory","HCC.SQL.Document.MedicationUseHistory")
    Set tSec("用药章节")=$LB("MedicationUseHistory","HCC.SQL.Document.MedicationUseHistory")
    Set tSec("行政管理章节")=$LB("Administration","HCC.SQL.Document.Administration")
    Set tSec("治疗计划章节")=$LB("TreatmentPlan","HCC.SQL.Document.TreatmentPlan")
    Set tSec("费用章节")=$LB("Payment","HCC.SQL.Document.Payment")
    Set tSec("卫生事件章节")=$LB("HealthcareEvent","HCC.SQL.Document.HealthcareEvent")
    Set tSec("主诉章节")=$LB("ChiefComplaint","HCC.SQL.Document.ChiefComplaint")
    Set tSec("现病史章节")=$LB("PresentIllnessHistory","HCC.SQL.Document.PresentIllnessHistory")
    Set tSec("抢救记录章节")=$LB("RescueRecord","HCC.SQL.Document.RescueRecord")
    Set tSec("其他相关信息章节")=$LB("Other","HCC.SQL.Document.Other")
    Set tSec("其他处置章节")=$LB("OtherProc","HCC.SQL.Document.OtherProc")
    Set tSec("检查报告章节")=$LB("CheckReport","HCC.SQL.Document.CheckReport")
    Set tSec("检验报告章节")=$LB("LabReport","HCC.SQL.Document.LabReport")
    Set tSec("失血章节")=$LB("BloodLoss","HCC.SQL.Document.BloodLoss")
    Set tSec("输血章节")=$LB("BloodTransfusion","HCC.SQL.Document.BloodTransfusion")
    Set tSec("麻醉章节")=$LB("Anesthesias","HCC.SQL.Document.Anesthesia")
    Set tSec("输液章节")=$LB("Infusion","HCC.SQL.Document.Infusion")
    Set tSec("术后去向章节")=$LB("ProcedureDisposition","HCC.SQL.Document.ProcedureDisposition")
    Set tSec("一般状况检查章节")=$LB("GeneralStatus","HCC.SQL.Document.GeneralStatus")
    Set tSec("产前检查章节")=$LB("PrenatalEvent","HCC.SQL.Document.PrenatalEvent")
    Set tSec("阴道分娩章节")=$LB("VaginalDelivery","HCC.SQL.Document.VaginalDelivery")
    Set tSec("产后处置章节")=$LB("ProcessPostDelivery","HCC.SQL.Document.ProcessPostDelivery")
    Set tSec("新生儿章节")=$LB("NewBorn","HCC.SQL.Document.NewBorn")
    Set tSec("分娩评估章节")=$LB("DeliveryAssessment","HCC.SQL.Document.DeliveryAssessment")
    Set tSec("四肢章节")=$LB("Extremities","HCC.SQL.Document.Extremities")
    Set tSec("皮肤章节")=$LB("Skins","HCC.SQL.Document.Skin")
    Set tSec("健康评估章节")=$LB("Assessment","HCC.SQL.Document.Assessment")
    Set tSec("健康指导章节")=$LB("HealthGuidance","HCC.SQL.Document.HealthGuidance")
    Set tSec("护理记录章节")=$LB("NursingRecord","HCC.SQL.Document.NursingRecord")
    Set tSec("护理标志章节")=$LB("NursingSign","HCC.SQL.Document.NursingSign")
    Set tSec("手术评估记录标志章节")=$LB("ProcedureAssessment","HCC.SQL.Document.ProcedureAssessment")
    Set tSec("护理隔离章节")=$LB("NursingIsolation","HCC.SQL.Document.NursingIsolation")
    Set tSec("器械物品核对章节")=$LB("InstrumentVerification","HCC.SQL.Document.InstrumentVerification")
    Set tSec("术后交接章节")=$LB("PostoperationHandover","HCC.SQL.Document.PostoperationHandover")
    Set tSec("入院信息章节")=$LB("AdmissionInformation","HCC.SQL.Document.AdmissionInformation")
    Set tSec("健康评估章节")=$LB("HealthAssessment","HCC.SQL.Document.HealthAssessment")
    Set tSec("生活方式章节")=$LB("LifeStyle","HCC.SQL.Document.LifeStyle")
    Set tSec("风险章节")=$LB("Risk","HCC.SQL.Document.Risk")
    Set tSec("意见章节")=$LB("Suggestion","HCC.SQL.Document.Suggestion")
    Set tSec("知情同意章节")=$LB("Consent","HCC.SQL.Document.Consent")
    Set tSec("转科记录章节")=$LB("Referral","HCC.SQL.Document.Referral")
    Set tSec("会诊原因章节")=$LB("ConsultReason","HCC.SQL.Document.ConsultReason")
    Set tSec("会诊意见章节")=$LB("ConsultSuggestion","HCC.SQL.Document.ConsultSuggestion")
    Set tSec("病历摘要章节")=$LB("MRSummary","HCC.SQL.Document.MRSummary")
    Set tSec("注意事项章节")=$LB("Attention","HCC.SQL.Document.Attention")
    Set tSec("术前总结章节")=$LB("PreoperativeSummary","HCC.SQL.Document.PreoperativeSummary")
    Set tSec("死亡原因章节")=$LB("DeathReason","HCC.SQL.Document.DeathReason")
    Set tSec("尸检意见章节")=$LB("AutopsyOpinion","HCC.SQL.Document.AutopsyOpinion")
    Set tSec("讨论内容章节")=$LB("Discussion","HCC.SQL.Document.Discussion")
    Set tSec("讨论总结章节")=$LB("DiscussionSummary","HCC.SQL.Document.DiscussionSummary")
    Set tSec("高值耗材章节")=$LB("HighValueConsumables","HCC.SQL.Document.HighValueConsumable")
    Set tSec("护理观察章节")=$LB("NursingObservations","HCC.SQL.Document.NursingObservation")
    Set tSec("症状章节")=$LB("Symptoms","HCC.SQL.Document.Symptom")
    Set tSec("用药管理章节")=$LB("MedicationAdministereds","HCC.SQL.Document.MedicationAdministered")
    Set tSec("体格检查章节")=$LB("PhysicalExams","HCC.SQL.Document.PhysicalExam")
    Set tSec("检查报告体格检查章节")=$LB("ERPhysicalExam","HCC.SQL.Document.ExamReportPhysicalExam")
    Set tSec("家族史章节")=$LB("FamilyHistories","HCC.SQL.Document.FamilyHistory")
    Set tSec("生命体征章节")=$LB("VitalSigns","HCC.SQL.Document.VitalSign")
    Set tSec("预防接种史章节")=$LB("Vaccinations","HCC.SQL.Document.Vaccination")
    Set tSec("社会史/个人史章节")=$LB("SocialHistory","HCC.SQL.Document.SocialHistory")
    Set tSec("护理操作章节")=$LB("NursingOperations","HCC.SQL.Document.NursingOperation")
    Set tSec("辅助检查章节")=$LB("SupplementaryExams","HCC.SQL.Document.SupplementaryExam")

    try
    {
        // 打开已有文档
        Set tDoc = ##class(HCC.SQL.Document).%OpenId(pDocNo)
        Return:(tDoc="") $$$ERROR(-100001,"文档不存在:"_pDocNo)
        // 先清除文档所有章节(非关系章节)
        Do tDoc.ClearSections()
        
        // 文档头必须存在
        Set tDocHeader = ##class(HCC.SQL.Document.Header).%OpenId(pDocNo)
        Return:(tDocHeader="") $$$ERROR(-100001,"文档头不存在:"_pDocNo)
        // 文档头关联就诊场景
        Do tDocHeader.SetEncounter(pDocNo)
        Do tDocHeader.%Save()
        // 关联文档头
        Do tDoc.SetHeader(pDocNo)
        
        // 获取文档类型
        Set tDocType = tDoc.DocumentType
        
        // 查询文档章节约束
        Set tSQL="SELECT DocumentSection,Cardinality FROM WS_DOC.DocumentConfig WHERE DocumentType="_tDocType
        set tStatement=##class(%SQL.Statement).%New()
        set tSC=tStatement.%Prepare(tSQL)
        if $$$ISERR(tSC) { do $system.OBJ.DisplayError(tSC) }
        set tRS=tStatement.%Execute()
        
        // 关联并检查文档章节约束
        while tRS.%Next() 
        {
            Set tSecName = tRS.%Get("DocumentSection"), tCard = tRS.%Get("Cardinality")
            
            // 需要特殊处理的文档章节:
            // 对《宫剖产记录》，"手术操作章节"使用"宫剖产手术操作章节"
            If (tSecName="手术操作章节") && (tDocType=16) 
            {
                Set tSecName="宫剖产手术操作章节"
            }
            // 对《检查报告》,"体格检查章节"使用"检查报告体格检查章节"
            If (tSecName="体格检查章节") && (tDocType=6) 
            {
                Set tSecName="检查报告体格检查章节"
            }
            
            Set tPropName = $lg(tSec(tSecName),1),
            tPropclass = $lg(tSec(tSecName),2),
            tRelationShip=0
            
            Set tRelationShip = ..#tRSList[tPropclass
            
            // 是关系(relationships)章节
            If (tRelationShip)
            {
                Set x=$PROPERTY(tDoc,tPropName)
                // 是否检查章节约束
                If ($bit(^WS.Setting.Validation,3)=1)&&((tCard="1..1")||(tCard="1..*")) && (x.Count()=0)
                {
                    Set tErrlog = tErrlog_" 缺失"_tSecName_";"
                }
            }
            Else // 是普通章节
            {            
                Do $METHOD(tDoc,"Set"_tPropName,pDocNo)
                // 是否检查章节约束
                If ($bit(^WS.Setting.Validation,3)=1)&&((tCard="1..1")||(tCard="1..*")) && ($PROPERTY(tDoc,tPropName)="")
                {
                    Set tErrlog = tErrlog_" 缺失"_tSecName_";"
                }
            }
        }
        kill tRS
        Return:(tErrlog '="") $$$ERROR(-100001,tErrlog)
        
        // 检查数据元基数约束
        If $bit(^WS.Setting.Validation,2)=1
        {
            Set tSC = tDoc.CheckDECardinality(tDoc.DocumentType,tDoc.DocumentNo)
            Return:($$$ISERR(tSC)) $$$ERROR(-100001,"DataElement Cardinality check error, please see HIP_DataGov.Log with RecordId="_tDoc.DocumentNo)
        }
        
        // Debug模式下，输出XML到文件
        If ($G(^HCC("Debug"))=1)
        {
            Set tFile = ##class(%Stream.FileCharacter).%New()
            Set tSplit=$Case($system.Version.GetOS(),"Windows":"\",:"/")
            Set tFilePath = $ZStrip($G(^HCC("Debug","SQLDocOutputFolder")), "<>W")
            if ($E(tFilePath,$L(tFilePath))'="\") || ($E(tFilePath,$L(tFilePath))'="/") 
            {
                Set tFilePath = tFilePath_tSplit
            }

            Set tSC=tFile.LinkToFile(tFilePath_pDocNo_".xml")
            Set tFile.TranslateTable = "UTF8"
            Set tSC = tDoc.XMLExportToStream(tFile)
            Do tFile.%Save()
            Do tFile.%Close()
        }

        Set tSC = tDoc.XMLExportToStream(.pDoc)
        
        // 保存tDoc
        Set tSC = tDoc.%Save()
        Do tDoc.%Close()
        Return tSC
    }
    catch (e)
    {
        Return e
    }
}

/// 删除SQL文档记录,pDocNo为文档号
/// 注意：该方法会删除对应文档的SQL数据！
ClassMethod ClearDoc(pDocNo) As %Status
{
    //删除其它主外键引用类
    &SQL(START TRANSACTION )
    &SQL(delete from HCC_SQL_Document_Header.EncompassingEncounter where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Header where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.PastHistory where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.MenstrualHistory where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Allergy where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Hospitalization where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HospitalCourse where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Diagnosis where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HealthProblem where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Referral where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HospitalDischargeDX where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HospitalAdmissionDX where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.SurgicalOperationNotePreoperativeDX where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.SurgicalOperationNotePostoperativeDX where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.LabTest where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ProviderOrder where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document."Procedure" where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ProcedureNote where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.CaesareanProcedure where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.SurgicalDrains where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.MedicationUseHistory where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Administration where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.TreatmentPlan where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Payment where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HealthcareEvent where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ChiefComplaint where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.PresentIllnessHistory where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.RescueRecord where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Other where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.OtherProc where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.CheckReport where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.LabReport where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.BloodLoss where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.BloodTransfusion where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Anesthesia where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Infusion where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ProcedureDisposition where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.GeneralStatus where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.PrenatalEvent where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.VaginalDelivery where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ProcessPostDelivery where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.NewBorn where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.DeliveryAssessment where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Extremities where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HealthAssessment where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HealthGuidance where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.NursingRecord where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.NursingObservation where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.NursingOperation where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.NursingSign where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ProcedureAssessment where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.NursingIsolation where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.InstrumentVerification where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.PostoperationHandover where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.AdmissionInformation where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.HealthAssessment where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.LifeStyle where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Risk where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Suggestion where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Consent where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Referral where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ConsultReason where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ConsultSuggestion where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.MRSummary where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Attention where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.PreoperativeSummary where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.DeathReason where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.AutopsyOpinion where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.Discussion where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.DiscussionSummary where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.ExamReportPhysicalExam where DocumentNo=:pDocNo)
    &SQL(delete from HCC_SQL_Document.SocialHistory where DocumentNo=:pDocNo)
    &SQL(COMMIT)
       
    //删除文档体和多有父子关系子类实例
    Set tSC= ##class(HCC.SQL.Document).%DeleteId(pDocNo)

    Quit tSC
}

}
